;实验10（2）：用子程序解决除法溢出的问题
;子程序名称：divdw
;功能：进行不会溢出的除法运算，被除数为dword型，除数为word型，结果为dword型
;参数： (ax)=dword型数据的低16位(L)
;		(dx)=dword型数据的高16位(H)
;		(cx)=除数
;返回：	(dx)=结果的高16位，(ax)=结果的低16位
;		(cx)=余数
;课本中提供了一个公式：X/N = INT(H/N)*65536 + [REM(H/N)*65536+L] / N；式中的*65536是等于左移4位，并不用真乘。
assume cs:code

code segment
	start:
		mov ax,4240h
		mov dx,000fh
		mov cx,0ch				;课本上的除以0ah，余数为零，不方便验证，所以我把除数改为0ch，这样余数为4
		call divdw
		mov ax,4c00h
		int 21h
	
	divdw:
		push ax 				;把低16位入栈先，多项式第二项需要再次用到
		
		;多项式第一项：
		;得用 32位 来存储 被除数 
		;高16位(000fh)除以除数0ch，因为dx中已经有高16位，000fh已经相当于000f0000了，所以不需要乘以65536
		mov ax,dx 				;ax放入被除数高位：000fh
		mov dx,0				;dx 置 0 (32位被除数思密达！)
		div cx					;商存于ax中，余数在dx中
		mov bx,ax 				;商暂存于bx(即多项式第一项)
		
		;多项式第二项：
		;余数已经在dx中了，正好可以作为多项式第二项的被除数，左移四位已经默认完成，所以，并不需要真的乘以65536
		pop ax 					;低16位放于ax 
		div cx 					;dxax连接的数 除以 cx，得到第二项, 商在ax，余数在dx 里。
		mov cx,dx				;余数放于cx
		mov dx,bx 				;高16位放于dx 里，一切OK
		
		ret

code ends
end start
